﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;

namespace Apex.Commons.ServiceRegistrationCenter
{
    /// <summary>
    /// 提供用于运行模块初始化器的扩展方法。每个项目都可以编写实现了IModuleInitializer接口的类，在其中注册所需的服务，从而避免将所有内容注册到入口项目中
    /// </summary>
    public static class ModuleInitializerExtensions
    {
        /// <summary>
        /// 在给定的程序集集合中运行模块初始化器，用于注册所需的服务
        /// </summary>
        /// <param name="services">IServiceCollection实例，用于注册服务</param>
        /// <param name="assemblies">包含模块初始化器的程序集集合</param>
        /// <returns>已注册所需服务的IServiceCollection实例</returns>
        public static IServiceCollection RunModuleInitializers(this IServiceCollection services,
            IEnumerable<Assembly> assemblies)
        {
            foreach (var asm in assemblies) // 遍历给定的程序集集合
            {
                Type[] types = asm.GetTypes(); // 获取程序集中的所有类型
                var moduleInitializerTypes = types.Where(t => !t.IsAbstract && typeof(IModuleInitializer).IsAssignableFrom(t)); // 筛选出所有实现了IModuleInitializer接口的非抽象类型
                foreach (var implType in moduleInitializerTypes) // 遍历每个模块初始化器类型
                {
                    var initializer = (IModuleInitializer?)Activator.CreateInstance(implType); // 创建模块初始化器实例
                    if (initializer == null) // 如果初始化器实例为空
                    {
                        throw new ApplicationException($"Cannot create ${implType}"); // 抛出异常
                    }
                    initializer.Initialize(services); // 调用模块初始化器的Initialize方法注册服务
                }
            }
            return services; // 返回已注册所需服务的IServiceCollection实例
        }
    }
}
